package cn.jtfadmin.core.modules.sys.service.impl;

import cn.jtfadmin.base.lang.common.domain.dto.ResultDTO;
import cn.jtfadmin.base.lang.common.domain.dto.SpecPDTO;
import cn.jtfadmin.base.lang.common.service.BaseService;
import cn.jtfadmin.base.lang.common.utils.JsonUtils;
import cn.jtfadmin.core.modules.sys.domain.dto.*;
import cn.jtfadmin.core.modules.sys.domain.entity.SysPermissionEntity;
import cn.jtfadmin.core.modules.sys.domain.entity.SysRoleEntity;
import cn.jtfadmin.core.modules.sys.domain.entity.SysUserEntity;
import cn.jtfadmin.core.modules.sys.service.SysRolePermissionActionService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Validated
@AllArgsConstructor
public class SysRolePermissionActionServiceImpl implements SysRolePermissionActionService {


    private BaseService<SysRoleEntity> sysRoleEntityBaseService;


    private BaseService<SysPermissionEntity> sysPermissionEntityBaseService;


    private BaseService<SysUserEntity> sysUserEntityBaseService;




    @Override
    @Transactional
    public ResultDTO<String> savePermissions(SysRolePermissionEditPDTO sysRolePermissionEditPDTO) {
        SysRoleEntity sysRoleEntity = sysRoleEntityBaseService.findRequiredById(sysRolePermissionEditPDTO.getRoleId());
        String permissionIds = sysRolePermissionEditPDTO.getPermissionIds();
        List<SysPermissionEntity> allPermission = sysPermissionEntityBaseService.findAll((SpecPDTO<SysPermissionEntity>) null);
        Set<String> allIds = new HashSet<>();
        Set<String> saveIds = StringUtils.commaDelimitedListToSet(permissionIds);
        for (String saveId : saveIds) {
            allIds.add(saveId);
            List<SysPermissionEntity> collect = allPermission.stream().filter(t -> Objects.equals(t.getId(), saveIds)).collect(Collectors.toList());
            for (SysPermissionEntity sysPermissionEntity : collect) {
                String parentIds = sysPermissionEntity.getParentIds();
                if (StringUtils.hasText(parentIds)) {
                    String[] s = StringUtils.delimitedListToStringArray(parentIds, ",", " ");
                    for (String s1 : s) {
                        if (StringUtils.hasText(s1)) {
                            allIds.add(s1);
                        }
                    }
                }
            }
        }
        sysRoleEntity.setPermissionList(
                allPermission.stream().filter(t -> allIds.contains(t.getId())).collect(Collectors.toList())
        );
        sysRoleEntityBaseService.save(sysRoleEntity);
        return ResultDTO.success();
    }

    @Override
    @Transactional
    public ResultDTO<String> deleteUserBatch(String roleId, String userIds) {
        Set<String> userIdSet = StringUtils.commaDelimitedListToSet(userIds);
        SysRoleEntity sysRoleEntity = sysRoleEntityBaseService.findRequiredById(roleId);
        List<SysUserEntity> userEntityList = sysRoleEntity.getUserList();
        sysRoleEntity.setUserList(userEntityList.stream()
                .filter(t -> !userIdSet.contains(t.getId())).collect(Collectors.toList()));
        sysRoleEntityBaseService.save(sysRoleEntity);
        return ResultDTO.success();
    }

    @Override
    public ResultDTO<String> grantUser(SysRoleUserGrantPDTO sysRoleUserGrantPDTO) {
        SysRoleEntity sysRoleEntity = sysRoleEntityBaseService.findRequiredById(sysRoleUserGrantPDTO.getRoleId());
        Set<String> userIdSet = new HashSet<>(sysRoleUserGrantPDTO.getUserIdList());
        sysRoleEntity.getUserList().forEach(t -> {
            userIdSet.remove(t.getId());
        });

        if (userIdSet.size() > 0) {
            List<SysUserEntity> userEntityList = new ArrayList<>(sysRoleEntity.getUserList());
            userEntityList.addAll(sysUserEntityBaseService.findByIds(userIdSet));
            sysRoleEntity.setUserList(userEntityList);
            sysRoleEntityBaseService.save(sysRoleEntity);
        }

        return ResultDTO.success();
    }

    @Override
    public List<String> parseDataRangeKey(String name, String dataRangeStr) {
        if (!StringUtils.hasText(dataRangeStr)) {
            return Collections.emptyList();
        }
        try {
            JsonNode jsonNode = JsonUtils.getObjectMapper().readTree(dataRangeStr);
            JsonNode node1 = jsonNode.get(name);
            if (Objects.isNull(node1)) {
                return Collections.emptyList();
            }
            if (node1.isArray()) {
                List<String> result = new ArrayList<>();
                for (JsonNode node : node1) {
                    result.add(node.asText());
                }
                return result;
            }
        } catch (JsonProcessingException e) {
            throw new RuntimeException();
        }

        return Collections.emptyList();
    }

}
